" -----------------------------------------------------------------------------  
"  < 判断是终端还是 Gvim >  
" -----------------------------------------------------------------------------  
if has("gui_running")  "{{{
    let g:isGUI = 1  
else  
    let g:isGUI = 0  
endif  "}}}
" Identify platform {
    silent function! OSX()
        return has('macunix')
    endfunction
    silent function! LINUX()
        return has('unix') && !has('macunix') && !has('win32unix')
    endfunction
    silent function! WINDOWS()
        return  (has('win32') || has('win64'))
    endfunction
" }
" Basics {
    if !WINDOWS()
        set shell=/bin/sh
    endif
" }

" Vundle plugin"{{{
set nocompatible              " be iMproved, required
filetype off                  " required

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')
" git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
" set the runtime path to include Vundle and initialize

" let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"=> 插件
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" 主题
Plugin 'altercation/vim-colors-solarized'
Plugin 'morhetz/gruvbox'

" ultisnips
Plugin 'sirver/ultisnips'

" snippets 这个不需要 python 支持
Plugin 'honza/vim-snippets'

" nerdtree
Plugin 'scrooloose/nerdtree'

" commenter
Plugin 'scrooloose/nerdcommenter'

" text-obj
Plugin 'kana/vim-textobj-user'

" auto-pairs
Plugin 'jiangmiao/auto-pairs'

" text-obj - a line: al
Plugin 'kana/vim-textobj-line'

" text-obj - entire: ae, ie
Plugin 'kana/vim-textobj-entire'

" text-obj - url: au, iu with or without tailing spaces
Plugin 'jceb/vim-textobj-uri'

" indentline
Plugin 'yggdroot/indentline'

" 支持更多插件提供的操作的点(.)操作
Plugin 'tpope/vim-repeat'

" vim-markdown
Plugin 'godlygeek/tabular'
Plugin 'plasticboy/vim-markdown'
" vim 表格插件
Plugin 'dhruvasagar/vim-table-mode'

" Markdown folding 不起作用
"Plugin 'nelstrom/vim-markdown-folding'

" Emmet 插件
Plugin 'mattn/emmet-vim'
" 用来给两端插东西很方便, 用法去 https://vimawesome.com/plugin/surround-vim 看 
Plugin 'tpope/vim-surround'

" kotlin
Plugin 'udalov/kotlin-vim'

" 美化状态栏
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'


" All of your Plugins must be added before the following line
call vundle#end()            " required
filetype plugin indent on    " required
" To ignore plugin indent changes, instead use:
"filetype plugin on
"
" Brief help
" :PluginList       - lists configured plugins
" :PluginInstall    - installs plugins; append `!` to update or just :PluginUpdate
" :PluginSearch foo - searches for foo; append `!` to refresh local cache
" :PluginClean      - confirms removal of unused plugins; append `!` to auto-approve removal
"
" see :h vundle for more details or wiki for FAQ
" Put your non-Plugin stuff after this line
"}}}
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"=>  全局设置
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" 设置 leader 键
let mapleader=","
let maplocalleader=","

" use utf-8
set encoding=utf-8

" 开启语法
syntax enable 
syntax on

" General recommended settings for editing "*.txt" files
set nocp et ts=4 sw=4 tw=80 ai

" 让第 80 列高亮
set cc=80

"设置命令行的高度 
set cmdheight=1 

" 自动保存
au FocusLost * silent! wa
let autosave=5

" 从不备份
set nobackup

" 不产生 swap file
set noswapfile

" 不产生 un~ 文件
set noundofile

" 解决 backspace 无法使用的问题
set backspace=indent,eol,start

" 去掉错误声
set noeb

" 自动缩进
set autoindent

" tab 宽度
set tabstop=4

" 统一缩进为 4
"set softtabstop=4
"set shiftwidth=4

" 不要用空格代替制表符
"set noexpandtab

" 设置行号
set nu

" Show line number, cursor position
set ruler

" inc 搜索
set incsearch
"高亮搜索的关键字 
set hlsearch 
"搜索忽略大小写 
set ignorecase 

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"=> 操作设置
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" 映射 jk -> esc, disable esc, ctrl+[
inoremap jk <esc>
vnoremap jk <esc>
inoremap <esc> <nop>
inoremap <c-[> <nop>

" 复制到 clipboard
set clipboard=unnamed
" 修复 jk 引起的粘贴 bug
set t_BE=

" 移动到行首, 行尾
nnoremap H ^
vnoremap H ^
nnoremap L $
vnoremap L $

" nmod 加入空行, 并返回 nmod
nnoremap <leader>j o<esc>k
" 折叠
"启动时不要自动折叠代码 
"set foldlevel=100 
" 折叠方式
set foldmethod=syntax
" 设置折叠切换为 <space> 
nnoremap <space> za

" 快速配置 .vimrc
nnoremap <leader>ev :vsplit ~/.vimrc<cr>
nnoremap <leader>sv :source ~/.vimrc<cr>

" 快速配置 snippets
" 1. all.snippets
nnoremap <leader>na :vsplit $VIM/vimfiles/UltiSnips/all.snippets<cr>
" 2. kotlin.snippets
nnoremap <leader>nk :vsplit $VIM/vimfiles/UltiSnips/kotlin.snippets<cr>
nnoremap <leader>nm :vsplit $VIM/vimfiles/UltiSnips/markdown.snippets<cr>
" 3. html.snippets
nnoremap <leader>nt :vsplit $VIM/vimfiles/UltiSnips/html.snippets<cr>

" Yank the word on cursor
nnoremap vv yiw

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"=> 字体, 主题
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" 颜色主题
colorscheme desert

" 设置代码配色方案  
"if g:isGUI  
	"colorscheme desert
    "colorscheme solarized
    "set background=dark
"else  
	"colorscheme molokai
    "set background=dark
    "colorscheme solarized
"endif 
" colorscheme solarized
colorscheme gruvbox
" set background=dark

" 高亮当前行和列
" set cursorcolumn
" set cursorline
" highlight CursorLine cterm=NONE ctermbg=188 ctermfg=NONE guibg=NONE guifg=NONE

" 字体
if g:isGUI  
    set guifont=Monaco:h16 
	" set guifont=Consolas:h14
	"set guifont=Ubuntu\ Mono\ derivative\ Powerline\ Regular\ 12
	"set guifontwide=Ubuntu\ Mono\ derivative\ Powerline\ Regular\ 12
	" 行间距
	"set linespace=-6
endif 

" 窗口最大化
if g:isGUI  
	set lines=200 columns=200
    " macvim 不支持下面的写法
    "autocmd GUIEnter * simalt ~x
endif

" 隐藏菜单栏, 工具栏, 滚动条
if g:isGUI  
	" Toggle Menu and Toolbar
	set guioptions-=m
	set guioptions-=T
	map <silent> <c-F11> :if &guioptions =~# 'T' <Bar>
			\set guioptions-=T <Bar>
			\set guioptions-=m <bar>
		\else <Bar>
			\set guioptions+=T <Bar>
			\set guioptions+=m <Bar>
		\endif<CR>

	" remove left-hand scroll bar
	set guioptions-=L  
	" remove right-hand scroll bar
	set guioptions-=r  
endif
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"                                    标签页配置                                "
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"""""""""""""""""""""""""""""""""
"  <tab>n, <tab>p, <leader>0-9  "
"   <tab>o/m 打开/关闭新标签页  "
"""""""""""""""""""""""""""""""""
"noremap <silent><tab>o :call Open_Explore(2)<cr>
noremap <silent><tab>o :tabnew<cr>
noremap <silent><tab>m :tabclose<cr>
noremap <silent><tab>n :tabn<cr>
noremap <silent><tab>p :tabp<cr>
noremap <silent><leader>1 :tabn 1<cr>
noremap <silent><leader>2 :tabn 2<cr>
noremap <silent><leader>3 :tabn 3<cr>
noremap <silent><leader>4 :tabn 4<cr>
noremap <silent><leader>5 :tabn 5<cr>
noremap <silent><leader>6 :tabn 6<cr>
noremap <silent><leader>7 :tabn 7<cr>
noremap <silent><leader>8 :tabn 8<cr>
noremap <silent><leader>9 :tabn 9<cr>
noremap <silent><leader>0 :tabn 10<cr>

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"  // tag::标签页[] 设置标签页只显示文件名, 不要路径[]  "
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" make tabline in terminal mode
function! Vim_NeatTabLine()
    let s = ''
    for i in range(tabpagenr('$'))
        " select the highlighting
        if i + 1 == tabpagenr()
            let s .= '%#TabLineSel#'
        else
            let s .= '%#TabLine#'
        endif
        " set the tab page number (for mouse clicks)
        let s .= '%' . (i + 1) . 'T'
        " the label is made by MyTabLabel()
        let s .= ' %{Vim_NeatTabLabel(' . (i + 1) . ')} '
    endfor
    " after the last tab fill with TabLineFill and reset tab page nr
    let s .= '%#TabLineFill#%T'
    " right-align the label to close the current tab page
    if tabpagenr('$') > 1
        let s .= '%=%#TabLine#%999XX'
    endif
    return s
endfunc
 
" get a single tab name 
function! Vim_NeatBuffer(bufnr, fullname)
    let l:name = bufname(a:bufnr)
    if getbufvar(a:bufnr, '&modifiable')
        if l:name == ''
            return '[No Name]'
        else
            if a:fullname 
                return fnamemodify(l:name, ':p')
            else
                return fnamemodify(l:name, ':t')
            endif
        endif
    else
        let l:buftype = getbufvar(a:bufnr, '&buftype')
        if l:buftype == 'quickfix'
            return '[Quickfix]'
        elseif l:name != ''
            if a:fullname 
                return '-'.fnamemodify(l:name, ':p')
            else
                return '-'.fnamemodify(l:name, ':t')
            endif
        else
        endif
        return '[No Name]'
    endif
endfunc
 
" get a single tab label
function! Vim_NeatTabLabel(n)
    let l:buflist = tabpagebuflist(a:n)
    let l:winnr = tabpagewinnr(a:n)
    let l:bufnr = l:buflist[l:winnr - 1]
    return Vim_NeatBuffer(l:bufnr, 0)
endfunc
 
" get a single tab label in gui
function! Vim_NeatGuiTabLabel()
    let l:num = v:lnum
    let l:buflist = tabpagebuflist(l:num)
    let l:winnr = tabpagewinnr(l:num)
    let l:bufnr = l:buflist[l:winnr - 1]
    return Vim_NeatBuffer(l:bufnr, 0)
endfunc
 
" setup new tabline, just like %M%t in macvim
set tabline=%!Vim_NeatTabLine()
set guitablabel=%{Vim_NeatGuiTabLabel()}
"""""""""""""""""""""
"  // end::标签页[] "
"""""""""""""""""""""
" ------------------------------------------
" 下面的只对 gvim/MacVim 起作用
" 直接在当前文件的路径下, 使用系统的文件查找窗口, 选中文件后在新的Tab里打开
function! s:Filter_Push(desc, wildcard)
    let g:browsefilter .= a:desc . " (" . a:wildcard . ")\t" . a:wildcard . "\n"
endfunc
 
let g:browsefilter = ''
call s:Filter_Push("All Files", "*")
call s:Filter_Push("C/C++/Object-C", "*.c;*.cpp;*.cc;*.h;*.hh;*.hpp;*.m;*.mm")
call s:Filter_Push("Python", "*.py;*.pyw")
call s:Filter_Push("Text", "*.txt")
call s:Filter_Push("Vim Script", "*.vim")
 
function! Open_Browse(where)
    let l:path = expand("%:p:h")
    if l:path == '' | let l:path = getcwd() | endif
    if exists('g:browsefilter') && exists('b:browsefilter')
        if g:browsefilter != ''
            let b:browsefilter = g:browsefilter
        endif
    endif
    if a:where == 0
        exec 'browse e '.fnameescape(l:path)
    elseif a:where == 1
        exec 'browse vnew '.fnameescape(l:path)
    else
        exec 'browse tabnew '.fnameescape(l:path)
    endif
endfunc

noremap <silent><m-o> :call Open_Browse(2)<cr>
inoremap <silent><m-o> :call Open_Browse(2)<cr>
""""""""""""""""""""""""
"  // end::打开文件[]  "
""""""""""""""""""""""""
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"=> 插件配置
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

""""""""""""""""""""""""""""""""""""""""
"=> nerdtree
""""""""""""""""""""""""""""""""""""""""
"" 是否显示隐藏文件
"let NERDTreeShowHidden=1
"" 不显示这些文件
let NERDTreeIgnore=['\.pyc$', '\~$', 'node_modules'] "ignore files in NERDTree

" nerdcommeter set up
" Add spaces after comment delimiters by default
let g:NERDSpaceDelims = 1

" Use compact syntax for prettified multi-line comments
let g:NERDCompactSexyComs = 1

" Align line-wise comment delimiters flush left instead of following code indentation
let g:NERDDefaultAlign = 'left'

" Set a language to use its alternate delimiters by default
let g:NERDAltDelims_java = 1

" Add your own custom formats or override the defaults
let g:NERDCustomDelimiters = { 'c': { 'left': '/**','right': '*/' } }

" Allow commenting and inverting empty lines (useful when commenting a region)
let g:NERDCommentEmptyLines = 1

" Enable trimming of trailing whitespace when uncommenting
let g:NERDTrimTrailingWhitespace = 1

" 新打开文件(标签页)时保持 nerdtree 打开
let NERDTreeQuitOnOpen=0

" nerdtree toggle
map <C-n> :NERDTreeToggle<CR>
" 调整分割窗口大小
" 水平
nmap    wk  :resize +3<CR>
nmap    wj  :resize -3<CR>
" 垂直
nmap    wh  :vertical resize -3<CR>
nmap    wl  :vertical resize +3<CR>

""""""""""""""""""""""""""""""""""""""""
"=> ultisnip  
""""""""""""""""""""""""""""""""""""""""

" ultisnip
let g:UltiSnipsExpandTrigger='<Tab>'
" list 用 c-n, c-p 选择就行了
" 下面的设置默认是 c-j, c-k 用默认的就好了
"let g:UltiSnipsJumpForwardTrigger='<c-j>'
"let g:UltiSnipsJumpBackwardTrigger='<c-k>'
let g:snips_author="Codergege"
""""""""""""""""""""""""""""""""""""""""
"=> indentline
""""""""""""""""""""""""""""""""""""""""

" Vim
let g:indentLine_color_term = 239

" GVim
let g:indentLine_color_gui = '#758A99'

" none X terminal
let g:indentLine_color_tty_light = 7 " (default: 4)
let g:indentLine_color_dark = 1 " (default: 2)

" Background (Vim, GVim)
let g:indentLine_bgcolor_term = 202
let g:indentLine_bgcolor_gui = '#A4E2C6'

""""""""""""""""""""""""""""""""""""""""
"=> markdown 相关  
""""""""""""""""""""""""""""""""""""""""

"let g:vim_markdown_folding_disabled=1
" conceal 功能很恶心, 绝对关闭
let g:vim_markdown_conceal = 0

" vim-table-mode For Markdown-compatible tables
let g:table_mode_corner='|'

""""""""""""""""""""""""""""""""""""""""
"=> vim-table-mode 相关  
""""""""""""""""""""""""""""""""""""""""
" 进入表格模式使用 ,tm (table mode)
" 使用 [count],tt(或 :Tableize{patten} 命令) 将选中的内容生成表格, 用 g:table_mode_delimiter 
" 定义表格的分隔符
let g:table_mode_delimiter=";;"
" You can use the following to quickly enable / disable table mode in insert mode by using || or __ 
function! s:isAtStartOfLine(mapping)
  let text_before_cursor = getline('.')[0 : col('.')-1]
  let mapping_pattern = '\V' . escape(a:mapping, '\')
  let comment_pattern = '\V' . escape(substitute(&l:commentstring, '%s.*$', '', ''), '\')
  return (text_before_cursor =~? '^' . ('\v(' . comment_pattern . '\v)?') . '\s*\v' . mapping_pattern . '\v$')
endfunction

inoreabbrev <expr> <bar><bar>
          \ <SID>isAtStartOfLine('\|\|') ?
          \ '<c-o>:TableModeEnable<cr><bar><space><bar><left><left>' : '<bar><bar>'
inoreabbrev <expr> __
          \ <SID>isAtStartOfLine('__') ?
          \ '<c-o>:silent! TableModeDisable<cr>' : '__'

""""""""""""""""""""""""""""""""""""""""
"=> Emmet 相关  
""""""""""""""""""""""""""""""""""""""""
let g:user_emmet_mode='a'    "enable all function in all mode.
" Enable just for html/css/markdown
let g:user_emmet_install_global = 0
autocmd FileType html,css,markdown EmmetInstall
"To remap the default <C-Y> leader:
"Note that the trailing , still needs to be entered, so the new keymap would be <C-Z>,.
"let g:user_emmet_leader_key='<C-Z>'

""""""""""""""""""""
"  surrond.vim 相关  "
""""""""""""""""""""
" surround_45 是指下划线 _ , 用 yss- 就可以整行两端添加删除线了
autocmd FileType markdown let b:surround_45 = "~~\r~~"

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"=> autocmd
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" autocmd event pattern command
" 自动检测 event, 如果符合 pattern, 就执行 command

" autocmd group
augroup codergege
" 防止重复载入
autocmd!

""""""""""""""""""""

" nerdtree 自动打开 nerdtree, 并将光标停留在右侧编辑区
autocmd vimenter * NERDTree
wincmd w
autocmd VimEnter * wincmd w
" nerdtree 只剩 nerdtree 窗口时关闭 vim
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif

""""""""""""""""""""

" markdown filetype file
au BufRead,BufNewFile *.{md,mdown,mkd,mkdn,markdown,mdwn} set filetype=markdown
au BufRead,BufNewFile *.{md,mdown,mkd,mkdn,markdown,mdwn}.{des3,des,bf,bfa,aes,idea,cast,rc2,rc4,rc5,desx} set filetype=markdown

" 设置 html, js, css 文件的 foldmethod=syntax
au BufRead,BufNewFile *.{html,js,css} set foldmethod=syntax

" 设置 js 文件的 set foldmethod=syntax
" au BufRead,BufNewFile *.{js} set foldmethod=syntax

" 设置 gradle 配置文件的折叠方法为 marker
au BufRead,BufNewFile *.{gradle} set foldmethod=marker

" html 文件 ,f -> fold 当前 tag
" autocmd FileType html nnoremap <buffer> <localleader>f Vatzf

" 一般 BufNewFile,BufRead 这两个事件都会一起使用
" 编辑 html 文件时, 不 wrap 
autocmd BufNewFile,BufRead *.{html,js,css,jsp,xml} set nowrap
augroup END

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"=> 外部工具
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" ,mt: markdown 转 html
" toc 深度设置为 4: 默认是 3, 只生成到 ### 一级.
nmap <leader>mt :update<CR>:!pandoc --toc --toc-depth=4 -c pandoc.css -f markdown -t html % -o %:r.html <CR>

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"=> FUNCTION
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

""""""""""""""""""""""""""""""""""""""""
"=> 最大化当前窗口
""""""""""""""""""""""""""""""""""""""""

function! Zoom ()
    " check if is the zoomed state (tabnumber > 1 && window == 1)
    if tabpagenr('$') > 1 && tabpagewinnr(tabpagenr(), '$') == 1
        let l:cur_winview = winsaveview()
        let l:cur_bufname = bufname('')
        tabclose

        " restore the view
        if l:cur_bufname == bufname('')
            call winrestview(cur_winview)
        endif
    else
        tab split
    endif
endfunction

nnoremap <leader>z :call Zoom()<CR>

""""""""""""""""""""""""""""""""""""""""
"=> 用 firfox 浏览当前文件
""""""""""""""""""""""""""""""""""""""""
 
function! ViewInBrowser(name)
    let file = expand("%:p")
    let l:browsers = {
        \"cr":"open -a \"Google Chrome\"",
        \"ff":"firefox",
    \}
	" 放在 xxx 文件夹中的文件用 http 协议打开.
    let htdocs='/home/codergege/xxx'
    let strpos = stridx(file, substitute(htdocs, '\\\\', '\', "g"))
    let file = '"'. file . '"'
    exec ":update " .file
    "echo file .' ## '. htdocs
    if strpos == -1
        exec ":silent ! ". l:browsers[a:name] ." file://". file
    else
        let file=substitute(file, htdocs, "http://127.0.0.1:8090/", "g")
        let file=substitute(file, '\\', '/', "g")
        exec ":silent ! ". l:browsers[a:name] file
    endif
endfunction

"nmap <Leader>cb :call ViewInBrowser("cr")<cr>
"nmap <Leader>fb :call ViewInBrowser("ff")<cr>
nmap <Leader>ff :!firefox %<cr>
" 用 typora 浏览
nmap <Leader>pp :!Typora %<cr>

""""""""""""""""""""""""""""""""""""""""
"=> markdown folding
""""""""""""""""""""""""""""""""""""""""

" 听说 vim8.0 已经支持 markdown 折叠了?
let g:markdown_folding=1
" 但是下面这个是 vim-markdown 插件的设置... 起作用了
let g:vim_markdown_folding_level = 4

" 不要折叠一, 二级标题, 从三级标题开始折叠
" function! MarkdownLevel()
    " if getline(v:lnum) =~ '^# .*$'
        " return ">1"
    " endif
    " if getline(v:lnum) =~ '^## .*$'
        " return ">2"
    " endif
    " if getline(v:lnum) =~ '^### .*$'
        " return ">1"
    " endif
    " if getline(v:lnum) =~ '^#### .*$'
        " return ">2"
    " endif
    " if getline(v:lnum) =~ '^##### .*$'
        " return ">3"
    " endif
    " if getline(v:lnum) =~ '^###### .*$'
        " return ">4"
    " endif
    " return "="
" endfunction
"
" au BufEnter *.md setlocal foldexpr=MarkdownLevel()
" au BufEnter *.md setlocal foldmethod=expr
